package com.ojoin.trade.common.utils.json;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.github.miemiedev.mybatis.paginator.jackson2.PageListJsonSerializer;
import com.ojoin.trade.common.utils.LogUtils;
/**
 * 注解spring-mvc缺省mapper
 * @author huanggc
 *
 */
@Component
public class JSONUtils {
	
	 private static final Logger logger = LoggerFactory.getLogger(JSONUtils.class);  

	 private static final ObjectMapper mapper;  
	
	 private static final String DEFAULT_DATE_FORMAT="yyyy-MM-dd HH:mm:ss";  
       
     public ObjectMapper getMapper() {  
             return mapper;  
     }  

     static {  
             SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);  
               
             mapper = new ObjectMapper();  
             mapper.setDateFormat(dateFormat);  
             
             mapper.addMixInAnnotations(Object.class, PropertyFilterMixIn.class);

    	    String[] ignorableFieldNames = { "tableName", "rowCreateTime" };  
    	    FilterProvider filters = new SimpleFilterProvider()  
    	      .addFilter("filter properties by name",   
    	       SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));  
    	    mapper.setFilters(filters);
    	    
             mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
             // 空值处理为空串
             mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
     			@Override
     			public void serialize(Object value, JsonGenerator jgen,
     					SerializerProvider provider) throws IOException,
     					JsonProcessingException {
     				jgen.writeString("");
     			}
             });
     		// 进行HTML解码。
     		mapper.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
     			@Override
     			public void serialize(String value, JsonGenerator jgen,
     					SerializerProvider provider) throws IOException,
     					JsonProcessingException {
     				jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
     			}
             }));
     		// 设置时区
     		mapper.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")
     		
            //add PageList
            SimpleModule module = new SimpleModule("PageListJSONModule",
     				new Version(1, 0, 0, null, null, null));
     		module.addSerializer(PageList.class, new PageListJsonSerializer(mapper));
     		mapper.registerModule(module);
     }  
       
     
	public static String  toJSONString(Object obj){
		Writer write = new StringWriter();  
		try {  
			mapper.writeValue(write, obj);  
        } catch (JsonGenerationException e) {  
        	LogUtils.error(logger,e,"JsonGenerationException when serialize object to json");  
        } catch (JsonMappingException e) {  
        	LogUtils.error(logger,e,"JsonMappingException when serialize object to json");  
        } catch (IOException e) {  
        	LogUtils.error(logger,e,"IOException when serialize object to json");  
        }  
		return write.toString();
	}
	
	public static <T> T  parseObject(String jsonStr,Class<T> clazz){
		 Object object = null;  
	        try {  
	            object = mapper.readValue(jsonStr, clazz);  
	        } catch (JsonParseException e) {  
	        	LogUtils.error(logger,e,"JsonParseException when serialize object to json");  
	        } catch (JsonMappingException e) {  
	        	LogUtils.error(logger,e,"JsonMappingException when serialize object to json");  
	        } catch (IOException e) {  
	        	LogUtils.error(logger,e,"IOException when serialize object to json");  
	        }  
	        return (T) object;  
	}
	
	public static class JsonDateSerializer extends JsonSerializer<Date>{  
        private SimpleDateFormat dateFormat;  
        public JsonDateSerializer(String format) {  
             dateFormat = new SimpleDateFormat(format);  
            }  
          
        @Override  
        public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)  
                throws IOException, JsonProcessingException {  
            String value = dateFormat.format(date);  
            gen.writeString(value);  
        }  
    }  
}
